package com.sgb.contract.view.ui.details;

import android.content.Context;
import android.graphics.Point;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;

import androidx.core.content.res.ResourcesCompat;
import androidx.databinding.BindingAdapter;
import androidx.recyclerview.widget.RecyclerView;

import com.sgb.contract.BR;
import com.sgb.contract.R;
import com.sgb.contract.utils.ScreenUtil;
import com.sgb.contract.utils.SimpleNotifyListener;
import com.sgb.contract.view.widget.CustomDragView;
import com.sgb.contract.view.widget.GlideImageView;
import com.swgk.core.recyclerview.adapter.BaseRecycleAdapter;
import com.swgk.core.recyclerview.adapter.ItemViewHolder;
import com.swgk.core.util.MLog;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * SignContractAdapter
 * 维护建议：这个adapter 处理视图过多，任何adapter 里禁止写任何业务逻辑代码，它们应该写在对应的viewModel 里。
 * @author cyj
 */
public class SignContractAdapter extends BaseRecycleAdapter<String> {

    /** 印章视图规格大小 */
    private final int px48, px50;
    private final int screenWidth;
    private final int px200 = 200, anxPt = 842;
    private boolean isDragEnabled = true;
    private final ArrayList<Integer> chapterIdList = new ArrayList<>();
    private final BigDecimal pt1WithIn = new BigDecimal("0.01388");
    private final BigDecimal dp1WithIn = new BigDecimal("0.00625");
    /** 印章移除通知监听器 */
    private SimpleNotifyListener<Object> simpleNotifyListener;
    /** 动态的ItemViewHolder布局刷新通知监听器 */
    private SimpleNotifyListener<Object> holderCreateListener;
    private final Map<Integer, ItemViewHolder> holderMap = new HashMap<>();
    private final Map<String, CustomDragView.DragParams> dragParamsMap = new HashMap<>();
    private final Map<String, CustomDragView.DragParams> dragParams1Map = new HashMap<>();

    public SignContractAdapter(Context context, List<String> dataList) {
        super(context, R.layout.contract_item_sign_contract, dataList);
        // px48 = DisplayUtil.dip2px(context, 48); // 原型图的大小48dp
        px48 = new BigDecimal(anxPt).divide(new BigDecimal(ScreenUtil.getScreenWidth(context)), 5, BigDecimal.ROUND_HALF_UP)
                .multiply(new BigDecimal(px200)).setScale(0, BigDecimal.ROUND_UP).intValue();//(float) (anxPt / ScreenUtil.getScreenWidth(context)) * px200;
        px50 = px48;
        MLog.d("印章的大小值为: ", px48+"");
        screenWidth = ScreenUtil.getScreenWidth(context);
    }

    @BindingAdapter("bindAdapter")
    public static void recycleViewBindAdapter(RecyclerView recyclerView, RecyclerView.Adapter<ItemViewHolder> adapter) {
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void convert(ItemViewHolder holder, String url) {
        holder.setBinding(BR.url, url);
        holderMap.put(holder.getIndex_position(), holder);
        holder.getView(R.id.glideImageView).postDelayed(() -> {
            holder.getmBinding().getRoot().postInvalidate();
            if(null != holderCreateListener) {
                holderCreateListener.notifyAny(holder.getIndex_position() + 1);
            }
        }, 1000);
    }

    public void removeAllChapter() {
        if(holderMap.size() <= 0) {
            return;
        }
        for(Map.Entry<Integer, ItemViewHolder> holder : holderMap.entrySet()) {
            FrameLayout layout = holder.getValue().getView(R.id.fl);
            for(Integer id : chapterIdList) {
                View chapterView = holder.getValue().getView(id);
                if(null != chapterView) {
                    layout.removeView(chapterView);
                }
            }
        }
        dragParamsMap.clear();
        dragParams1Map.clear();
        chapterIdList.clear();
    }

    @Override
    public void setDatas(List<String> list) {
        holderMap.clear();
        dragParamsMap.clear();
        super.setDatas(list);
    }

    /**
     * 添加印章
     */
    public synchronized void addChapter(int position) {
        addChapter(position, 0, 0,true);
    }

    /**
     * 添加印章
     */
    public synchronized void addChapter(int position, int x, int y) {
        addChapter(position, x, y,false);
    }

    /**
     * 添加印章
     * fixme: 这是一个很长的方法，现在赶时间后面在优化 @cyj
     */
    public synchronized void addChapter(int position, int x, int y, boolean isDrawBorder) {
        ItemViewHolder holder = holderMap.get(position);
        if(null == holder) {
            return;
        }
        GlideImageView glideImageView = ((GlideImageView) holder.getView(R.id.glideImageView));
        int intrinsicWidth = glideImageView.getIntrinsicWidth();
        int intrinsicHeight = glideImageView.getIntrinsicHeight();
        if(intrinsicWidth <= 0) {
            // 无效的图片大小数值，一般指图片无法正常加载出来或者由于网络质量差加载慢导致先添加视图时进入此处拦截
            return;
        }
        FrameLayout layout = holder.getView(R.id.fl);
        CustomDragView customDragView = new CustomDragView(layout.getContext());
        customDragView.setId(customDragView.hashCode());
        chapterIdList.add(customDragView.getId());
        customDragView.setTag(position + "|" + customDragView.hashCode());
        customDragView.setLayoutParams(new FrameLayout.LayoutParams(-2, -2));
        if(x > 0 || y > 0) {
            //customDragView.setInitialPoint(dpX.intValue(), intrinsicHeight - dpY.intValue());
        } else {
            customPoint(position, customDragView, intrinsicHeight);
        }

        FrameLayout chapterLayout = new FrameLayout(layout.getContext());
        FrameLayout.LayoutParams chapterLp = new FrameLayout.LayoutParams(px48, px48);
        chapterLp.gravity = Gravity.CENTER;
        chapterLayout.setLayoutParams(chapterLp);
        chapterLayout.setBackground(ResourcesCompat.getDrawable(context.getResources(), R.mipmap.icon_chapter_bg, null));
        customDragView.addForegroundView(chapterLayout);

        if(isDrawBorder) {
            FrameLayout borderLayout = new FrameLayout(layout.getContext());
            borderLayout.setLayoutParams(new FrameLayout.LayoutParams(px50, px50));
            borderLayout.setBackground(ResourcesCompat.getDrawable(context.getResources(), R.drawable.contract_chapter_border_bg, null));
            customDragView.addParentTouchEventListener(event -> {
                if(MotionEvent.ACTION_MOVE == event.getAction() && View.GONE != borderLayout.getVisibility()) {
                    borderLayout.setVisibility(View.GONE);
                } else if(MotionEvent.ACTION_UP == event.getAction() && View.VISIBLE != borderLayout.getVisibility() ) {
                    borderLayout.setVisibility(View.VISIBLE);
                }
            });

            ImageView deleteImg = new ImageView(layout.getContext());
            deleteImg.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(), R.mipmap.icon_contract_delete, null));
            FrameLayout.LayoutParams imgLp = new FrameLayout.LayoutParams(-2, -2);
            imgLp.gravity = Gravity.END;
            deleteImg.setLayoutParams(imgLp);
            deleteImg.setOnClickListener(v -> {
                if(!isDragEnabled) {
                    return;
                }
                layout.removeView(customDragView);
                layout.invalidate();
                // 移除印章视图参数
                dragParamsMap.remove(null == customDragView.getTag() ? "" : customDragView.getTag());
                dragParams1Map.remove(null == customDragView.getTag() ? "" : customDragView.getTag());
                if(null != simpleNotifyListener) {
                    simpleNotifyListener.notifyAny(null);
                }
            });

            borderLayout.addView(deleteImg);
            customDragView.addBackgroundView(borderLayout);
        } else {
            // 拦截customDragView 的触摸事件，保证dragParamsMap 记录的点永远时自己添加的，而不是从网络获取回显在UI层的印章参数
            chapterLayout.setOnClickListener(null);
        }
        layout.addView(customDragView);

        customDragView.setDragListener(new CustomDragView.DragListener() {
            @Override
            public void onDrag(View view, int motionEventAction, CustomDragView.DragParams params) {
                if(MotionEvent.ACTION_UP == motionEventAction) {
                    dragParams1Map.put(view.getTag().toString(), params);
                    BigDecimal zoomW =BigDecimal.valueOf(params.x).divide(BigDecimal.valueOf(intrinsicWidth), 5, BigDecimal.ROUND_UP);
                    BigDecimal zoomH =BigDecimal.valueOf(params.y).divide(BigDecimal.valueOf(intrinsicHeight), 5, BigDecimal.ROUND_UP);
                    MLog.d("loadImageForUrl: 666", zoomW + " | " + zoomH);
                    BigDecimal X = zoomW.multiply(BigDecimal.valueOf(595));
                    BigDecimal Y = zoomH.multiply(BigDecimal.valueOf(842));
                    // 误差11
                    BigDecimal bang = BigDecimal.valueOf(48).multiply(dp1WithIn).divide(pt1WithIn, 5, BigDecimal.ROUND_HALF_UP);
                    MLog.d("loadImageForUrl: 7777", bang + " | " + Y);
                    Y = BigDecimal.valueOf(842).subtract(Y).subtract(bang);
                    MLog.d("loadImageForUrl: 8888", X + " | " + Y);
                    // 拖拽结束，记录保存坐标点
                    CustomDragView.DragParams dp = new CustomDragView.DragParams();
                    dp.x = X.intValue();
                    dp.y = Y.intValue();
                    MLog.d("TAG", "拖拽完成的y点坐标 " + dp.x + " | " + dp.y);
                    // {"signOnPage":"1","signLocationLBX":"362","signLocationLBY":"313","signLocationRUX":"437","signLocationRUY":"388"}
                    dragParamsMap.put(view.getTag().toString(), dp);
                }
            }

            @Override
            public boolean isEnabled() {
                return isDragEnabled;
            }
        });
    }

    /**
     * 设置通知监听
     * @param listener    SimpleNotifyListener
     */
    public void setViewRemoveListener(SimpleNotifyListener<Object> listener) {
        this.simpleNotifyListener = listener;
    }

    /**
     * 设置holder被创建的通知监听
     * 在动态的加载创建holder时才被许可添加印章视图
     * @param listener    SimpleNotifyListener<holder.position>
     */
    public void setHolderCreateListener(SimpleNotifyListener<Object> listener) {
        this.holderCreateListener = listener;
    }

    /**
     * 印章是否重叠了
     * 尽量避免短间隔调用，会轻微阻塞线程
     * @return    true是false否
     */
    public synchronized boolean hasChapterOverlap() {
        if(dragParamsMap.size() <= 1) {
            return false;
        }
        // 重叠判断，不太优化，3个章会判断6次，其中3次判断无意义
        for(Map.Entry<String, CustomDragView.DragParams> entry1 : dragParams1Map.entrySet()) {
            String index1 = entry1.getKey().substring(0, entry1.getKey().indexOf("|"));
            CustomDragView.DragParams params1 = entry1.getValue();
            for(Map.Entry<String, CustomDragView.DragParams> entry2 : dragParams1Map.entrySet()) {
                String index2 = entry2.getKey().substring(0, entry2.getKey().indexOf("|"));
                CustomDragView.DragParams params2 = entry2.getValue();
                if(params1.equals(params2)) {
                    continue;
                }
                if(index1.equals(index2) && Math.abs(params1.x - params2.x) < px48 && Math.abs(params1.y - params2.y) < px48) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 自定义顺序添加印章(与ios统一，左上，右上，右下 三个章位置依次排列)
     */
    private void customPoint(int position, CustomDragView customDragView, int parentHeight) {
        // 初始化定义命中区间数值
        // 定义命中区间数值（区间命中算法）
        Point[] points = new Point[]{new Point(0, 0), new Point((screenWidth - px48), 0), new Point(0, parentHeight - px48)};
        // 同一页/其他页 其他位置判断与设置
        for(Map.Entry<String, CustomDragView.DragParams> entry : dragParams1Map.entrySet()) {
            String index = entry.getKey().substring(0, entry.getKey().indexOf("|"));
            if(null != points[0] && index.equals(String.valueOf(position)) && entry.getValue().x == points[0].x && entry.getValue().y == points[0].y) {
                points[0] = null;
            } else if(null != points[1] && index.equals(String.valueOf(position)) && entry.getValue().x == points[1].x && entry.getValue().y == points[1].y) {
                points[1] = null;
            }
        }
        for(Point point : points) {
            if(null != point) {
                customDragView.setInitialPoint(point.x, point.y);
                return;
            }
        }
    }

    /**
     * 是否有添加印章
     * @return    true:是，法拉瑟：否
     */
    public boolean hasAddChapter() {
        return dragParamsMap.size() > 0;
    }

    /**
     * 获取自己添加的印章集合
     */
    public Map<String, CustomDragView.DragParams> getDragParamsMap() {
        return dragParamsMap;
    }

    /**
     * 获取印章的宽度。
     * 由于印章目前规定时正方形，因此获取一边就行了
     */
    public int getChapterWidth() {
        return 75;
    }

    /**
     * 设置印章是否可以拖拽
     * @param isEnabled
     */
    public void setDragEnabled(boolean isEnabled) {
        this.isDragEnabled = isEnabled;
    }
}
